#include "GamePlayState.h"
#include "Events\CSGD_EventSystem.h"
#include "../SGD Wrappers/SGD_Math.h"
#include "Game.h"
#include "Time.h"
#include "Emitter.h"
#include "Camera.h"
#include "AchievementManager.h"
#include "ProfileManager.h"
#include "MainMenuState.h"
#include "GameCompleteState.h"
#include "BitmapFont.h"
#include "AudioManager.h"


GamePlayState* GamePlayState::pInstance = nullptr;

/*static*/ GamePlayState* GamePlayState::GetInstance( void )
{
	// Allocate the static pointer if necessary
	if( pInstance == nullptr )
		pInstance = new GamePlayState;

	// Return the singleton
	return pInstance;
}
/*static*/ void GamePlayState::DeleteInstance( void )
{
	delete pInstance;
	pInstance = nullptr;
}

// Update
void GamePlayState::Update(float deltaTime)
{
	//Run normally if not paused
	if(!isPaused && !isOver)
	{
		CSGD_EventSystem::GetInstance()->ProcessEvents();
		if(dI->KeyPressed(DIK_ESCAPE) || dI->KeyPressed(DIK_P) || dI->JoystickButtonPressed(7) )
		{
			isPaused = true;
			pauseMenu.Enter();
			return;
		}
		if(ProfileManager::GetInstance()->getCurProfile().getControlScheme() == 5)
		{
			if(dI->JoystickButtonPressed(6))
			{
				isPaused = true;
				pauseMenu.Enter();
				return;
			}
		}

		if(player->GetIsOver())
		{
			isOver = true;
			levelCompleteMenu.Enter();
			return;
		}

		camera->Update(deltaTime);
		AchievementSystem::AchievementManager::GetInstance().Update(deltaTime);
		levelTimer.Update(deltaTime);

		//e->Update(deltaTime);
		//e2->Update(deltaTime);

		//Update all GameObjects
		objManager->UpdateAll(Time::GetInstance().DeltaTime());
		objManager->CheckAllCollisions();


	}
	else if(isOver == true)
	{
		levelCompleteMenu.Update(deltaTime);
	}
	//Update Pause Menu
	else
	{
		pauseMenu.Update(deltaTime);
	}
}

// Render
void GamePlayState::Render(void) const
{
	//Render game:
	//Render  background

	if( Game::GetInstance()->GetScreenWidth() != 800 && Game::GetInstance()->GetScreenHeight() != 600)
	{

		switch ( (int)(CurrentLevel / 5 ))
		{
		case 0:
			{
				CSGD_TextureManager::GetInstance()->Draw(ChapterOneImageID,0,0,0.95f,1.055f);
				break;
			}
		case 1:
			{
				CSGD_TextureManager::GetInstance()->Draw(ChapterTwoImageID,0,0,0.95f,1.055f);
				break;
			}
		case 2:
			{
				CSGD_TextureManager::GetInstance()->Draw(ChapterThreeImageID,0,0,0.95f,1.055f);
				break;
			}
		case 3:
			{
				CSGD_TextureManager::GetInstance()->Draw(ChapterFourImageID,0,0,0.95f,1.055f);
				break;
			}
		case 4:
			{
				CSGD_TextureManager::GetInstance()->Draw(ChapterFiveImageID,0,0,0.95f,1.055f);
				break;
			}
		}
	}
	else if( Game::GetInstance()->GetScreenWidth() == 800 && Game::GetInstance()->GetScreenHeight() == 600) 
	{
		switch ( (int)(CurrentLevel / 5 ))
		{
		case 0:
			{
				CSGD_TextureManager::GetInstance()->Draw(ChapterOneImageID,0,0,0.8f,0.6f);
				break;
			}
		case 1:
			{
				CSGD_TextureManager::GetInstance()->Draw(ChapterTwoImageID,0,0,0.8f,0.6f);
				break;
			}
		case 2:
			{
				CSGD_TextureManager::GetInstance()->Draw(ChapterThreeImageID,0,0,0.8f,0.6f);
				break;
			}
		case 3:
			{
				CSGD_TextureManager::GetInstance()->Draw(ChapterFourImageID,0,0,0.8f,0.6f);
				break;
			}
		case 4:
			{
				CSGD_TextureManager::GetInstance()->Draw(ChapterFiveImageID,0,0,0.8f,0.6f);
				break;
			}
		}
	}


	//Render all GameObjects
	objManager->RenderAll();

	AchievementSystem::AchievementManager::GetInstance().Render();
	levelTimer.Render();

	ostringstream oss;

	oss << "Level " << CurrentLevel / 5 + 1 << "." << (CurrentLevel % 5) + 1;

	BitmapFont::GetInstance()->Print(oss.str().c_str(), 175, 5, 0, 200, D3DCOLOR_ARGB(255,255,255,255)); 

	//e->Render();
	//e2->Render();

	static float angle = 0.0f;
	angle += Time::GetInstance().DeltaTime();
	if(angle > 6.2831852f)
		angle = 0.0f;

#pragma region Debug Linecast from Player
	/*
	if(player != nullptr)
	{

	LinecastInfo info;
	tVector2D start = { player->GetPosX(), player->GetPosY() };
	tVector2D dir;
	dir.fX = 0;
	dir.fY = -1;
	dir = Vector2DRotate(dir, angle);

	if(Physics::LineCast(info, 5000.0f, start, dir, "Player"))
	{
	float offsetX = Camera::GetInstance()->OffsetX();
	float offsetY = Camera::GetInstance()->OffsetY();

	CSGD_Direct3D::GetInstance()->DrawLine(player->GetPosX() - offsetX, player->GetPosY() - offsetY,
	info.point.fX - offsetX, info.point.fY - offsetY, D3DCOLOR_ARGB(255, 255, 0, 0), 3);
	}
	}
	*/
#pragma endregion

	if(isPaused)
	{
		RECT screenRect = {0,0,Game::GetInstance()->GetScreenWidth(),Game::GetInstance()->GetScreenHeight()};
		D3D->DrawRect(screenRect,D3DCOLOR_ARGB(75,0,0,0));
		//Render Pause Menu
		pauseMenu.Render();
	}

	if(isOver)
	{
		RECT screenRect = {0,0,Game::GetInstance()->GetScreenWidth(),Game::GetInstance()->GetScreenHeight()};
		D3D->DrawRect(screenRect,D3DCOLOR_ARGB(75,0,0,0));
		//Render level complete
		levelCompleteMenu.Render();
	}
}

// Enter
//	- Used to initialize the game state.
void GamePlayState::Enter(void)
{
	GameState::Enter();

	//Get object manager
	objManager = ObjectManager::GetInstance();
	CSGD_EventSystem::GetInstance()->RegisterClient("KillPlayer", player);
	camera = Camera::GetInstance();
	camera->SetPlayer(player);
	camera->SetExitDoor(nullptr);

}

// Enter
//	- Used to initialize the game state and start the game
//	  at the specified level.
//	- If the level index is invalid, the game will start at
//	  the default level.
void GamePlayState::Enter(unsigned int level)
{
	GameState::Enter();

	player = new Player();

	levelManager.LoadLevel(level);

	//Current Level
	CurrentLevel = level;
	levelTimer.ResetTimer();

	if( Game::GetInstance()->GetScreenWidth() != 800 && Game::GetInstance()->GetScreenHeight() != 600)
	{
		ChapterOneImageID = CSGD_TextureManager::GetInstance()->LoadTexture("Textures/cargo bay.jpg");
		ChapterTwoImageID = CSGD_TextureManager::GetInstance()->LoadTexture("Textures/plumbing sector BG.jpg");
		ChapterThreeImageID = CSGD_TextureManager::GetInstance()->LoadTexture("Textures/power sector BG.jpg");
		ChapterFourImageID = CSGD_TextureManager::GetInstance()->LoadTexture("Textures/science sector BG.jpg");
		ChapterFiveImageID = CSGD_TextureManager::GetInstance()->LoadTexture("Textures/command sector BG.jpg");
	}
	else if( Game::GetInstance()->GetScreenWidth() == 800 && Game::GetInstance()->GetScreenHeight() == 600) 
	{
		ChapterOneImageID = CSGD_TextureManager::GetInstance()->LoadTexture("Textures/Arcade/cargo bay.jpg");
		ChapterTwoImageID = CSGD_TextureManager::GetInstance()->LoadTexture("Textures/Arcade/plumbing sector BG.jpg");
		ChapterThreeImageID = CSGD_TextureManager::GetInstance()->LoadTexture("Textures/Arcade/power sector BG.jpg");
		ChapterFourImageID = CSGD_TextureManager::GetInstance()->LoadTexture("Textures/Arcade/science sector BG.jpg");
		ChapterFiveImageID = CSGD_TextureManager::GetInstance()->LoadTexture("Textures/Arcade/command sector BG.jpg");
	}

	//EmitterManager::GetInstance()->Load("fire", "test.xml", true, 400, 600 );
	//EmitterManager::GetInstance()->Load("firerain", "test2.xml", true, 400, 0 );

	//e = EmitterManager::GetInstance()->GetEmitter("fire");
	//e2 = EmitterManager::GetInstance()->GetEmitter("firerain");

	ObjectManager::GetInstance()->AddObject(4,player);
}

// Exit
//	- Used to clean up the game state.
void GamePlayState::Exit(void)
{
	objManager->RemoveAll();
	CSGD_EventSystem::GetInstance()->ClearEvents();
	GameState::Exit();
	DeleteInstance();
}

bool GamePlayState::LoadNextLevel(void)
{
	if(levelManager.LoadNextLevel())
	{
		CurrentLevel++;
		levelTimer.ResetTimer();
		CSGD_EventSystem::GetInstance()->ClearEvents();
		if(CurrentLevel > 19)
			AudioManager::GetInstance()->switchMusic("gameplay","menus");
		else if( CurrentLevel > 9)
		{
			AudioManager::GetInstance()->switchMusic("menus", "gameplay2");
		}
		else
		{
			AudioManager::GetInstance()->switchMusic("menus","gameplay");
		}
		return true;
	}
	else
	{
		Game::GetInstance()->ChangeState(GameCompleteState::GetInstance());
		return false;
	}
}

void GamePlayState::ReplayLevel(void)
{
	levelManager.LoadLevel(CurrentLevel);
	//CurrentLevel = levelManager.GetCurLevel();

	levelTimer.ResetTimer();
	CSGD_EventSystem::GetInstance()->ClearEvents();
}

GamePlayState::GamePlayState(void)
{
	isPaused = false;
	isOver = false;

	CurrentLevel = -1;
}

GamePlayState::~GamePlayState(void)
{
	camera->DeleteInstance();
}